package ua.khpi.si.kit49.diploma.controllers;

import java.security.Principal;
import java.util.Set;

import org.apache.log4j.Logger;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import ua.khpi.si.kit49.diploma.core.Constants;

/**
 * Controller is in charge of operation with authentication
 * 
 * @author netstalk3r
 * 
 */

@Controller
public class LoginController {

	/**
	 * Logger
	 */
	private static final Logger log = Logger.getLogger(LoginController.class);

	// mapping for dispatcher servlet
	private static final String DISPATCHER_PREFIX = "/pages";

	// /////////////////////////////////////////////////////////////////////////////
	// mapping for methods
	// /////////////////////////////////////////////////////////////////////////////
	private static final String SUCCESS_LOGIN_MAPPING = "/success";
	private static final String LOGIN_PAGE_MAPPING = "/login";
	private static final String LOGIN_FAILED_MAPPING = "/loginfailed";
	private static final String LOGOUT_MAPPING = "/logout";

	// /////////////////////////////////////////////////////////////////////////////

	/**
	 * methods invokes when authentication is success (never)
	 * 
	 * @param model
	 *            model map
	 * @param principal
	 *            of authorized user
	 * @param authentication
	 * @return redirect to routes page
	 */
	@RequestMapping(value = SUCCESS_LOGIN_MAPPING, method = RequestMethod.GET)
	public String succesLogin(ModelMap model, Principal principal,
			Authentication authentication) {
		String username = principal.getName();
		log.info("User name: " + username);
		Set<String> roles = AuthorityUtils.authorityListToSet(authentication
				.getAuthorities());
		log.info("User: " + username + "; role: " + roles);
		return "redirect:" + DISPATCHER_PREFIX + "/" + Constants.ROUTES_PAGE;
	}

	/**
	 * method for getting login page
	 * 
	 * @param model
	 *            model map
	 * @return login page
	 */
	@RequestMapping(value = LOGIN_PAGE_MAPPING, method = RequestMethod.GET)
	public String login(ModelMap model) {
		log.info("Attempt login");
		return Constants.LOGIN_PAGE;
	}

	/**
	 * method invokes when authorization fail
	 * 
	 * @param model
	 *            model map
	 * @return login page
	 */
	@RequestMapping(value = LOGIN_FAILED_MAPPING, method = RequestMethod.GET)
	public String loginerror(ModelMap model) {
		model.addAttribute("error", "true");
		return Constants.LOGIN_PAGE;
	}

	/**
	 * method invokes when user sing out
	 * 
	 * @param model
	 *            model map
	 * @return login page
	 */
	@RequestMapping(value = LOGOUT_MAPPING, method = RequestMethod.GET)
	public String logout(ModelMap model) {
		return Constants.LOGIN_PAGE;
	}

	/**
	 * method invokes when user want to get access to admin's pages
	 * 
	 * @param model
	 *            model map
	 * @param principal
	 *            of authorized user
	 * @param authentication
	 * @return error page
	 */
	@RequestMapping(value = "/403", method = RequestMethod.GET)
	public String accessDenied(ModelMap model, Principal principal,
			Authentication authentication) {
		Set<String> roles = AuthorityUtils.authorityListToSet(authentication
				.getAuthorities());
		log.info("Access denied: username - " + principal.getName()
				+ "; role - " + roles);
		model.put("errorMessage", "company.error.page.403.access.denied");
		return Constants.ERROR_PAGE;
	}
}
